/* =================================================================================
 File name:      PID_PMEASURE_H
 比例测量PID算法
 ===================================================================================*/

#ifndef _PID_PMEASURE_H_
#define _PID_PMEASURE_H_
#include <stdint.h>
#include <stdbool.h>
// Constants used in some of the functions below
/// 比例测量类型
typedef enum {
	P_ON_M = 0, P_ON_E = 1

} pid_measure_type;
/// 控制输出类型
typedef enum {
	AUTOMATIC = 1, MANUAL = 0

} pid_ctrl_model_type;
// 输出方向类型
typedef enum {
	DIRECT = 0, REVERSE = 1

} pid_out_dir_type;

typedef struct pid_pmeasure_ctrl {
	/* data */
	float dispKp; // * we'll hold on to the tuning parameters in user-entered
	float dispKi; //   format for display purposes
	float dispKd; //

	float kp; // * (P)roportional Tuning Parameter
	float ki; // * (I)ntegral Tuning Parameter
	float kd; // * (D)erivative Tuning Parameter

	pid_out_dir_type controllerDirection;
	pid_measure_type pOn;

	float *_input;    // * Pointers to the Input, Output, and Setpoint variables
	float *_output;  //   This creates a hard link between the variables and the
	float *_setpoint; //   PID, freeing the user from having to constantly tell us
					  //   what these values are.  with pointers we'll just know.

	unsigned long lastTime;
	float outputSum, lastInput;

	unsigned long SampleTime;
	float outMin, outMax;
	bool inAuto, pOnE;
} pid_pmeasure_ctrl_t;

pid_pmeasure_ctrl_t* pid_pmeasure_ctrl_new(float *input, float *output,
		float *setpoint, float kp, float ki, float kd, pid_measure_type pOn,
		pid_out_dir_type controllerDirection);

void pid_pmeasure_ctrl_delete(pid_pmeasure_ctrl_t *handle);

void pid_pmeasure_ctrl_set_model(pid_pmeasure_ctrl_t *handle,
		pid_ctrl_model_type model);

bool pid_pmeasure_ctrl_compute(pid_pmeasure_ctrl_t *handle);

void pid_pmeasure_ctrl_set_output_limits(pid_pmeasure_ctrl_t *handle, float Min,
		float Max);

void pid_pmeasure_ctrl_set_tunings(pid_pmeasure_ctrl_t *handle, float Kp,
		float Ki, float Kd, pid_measure_type POn);

void pid_pmeasure_ctrl_set_controller_direction(pid_pmeasure_ctrl_t *handle,
		pid_out_dir_type dir);

void pid_pmeasure_ctrl_set_sampletime(pid_pmeasure_ctrl_t *handle,
		int NewSampleTime);

float pid_pmeasure_ctrl_get_kp(pid_pmeasure_ctrl_t *handle);
float pid_pmeasure_ctrl_get_ki(pid_pmeasure_ctrl_t *handle);
float pid_pmeasure_ctrl_get_kd(pid_pmeasure_ctrl_t *handle);

pid_ctrl_model_type pid_pmeasure_ctrl_get_model(pid_pmeasure_ctrl_t *handle);

pid_out_dir_type pid_pmeasure_ctrl_get_direction(pid_pmeasure_ctrl_t *handle);

#endif // __PID_H__
